import { sys } from 'cc'
import { ZAssetManager } from './ZAssetManager'

/**
 * 基础设置管理器
 * 提供通用的设置加载、缓存和管理功能
 */
export abstract class ZBaseSettingManager<T extends object> {
	// 设置缓存键名，子类需要覆盖
	protected abstract readonly SETTINGS_CACHE_KEY: string

	// 默认设置资源路径，子类需要覆盖
	protected abstract readonly DEFAULT_SETTINGS_PATH: string

	// 需要持久化的属性键列表，子类需要设置
	protected abstract readonly PERSISTENT_KEYS: (keyof T)[]

	// 当前设置
	protected _settings: T = null

	// 默认设置
	protected _defaultSettings: T = null

	/**
	 * 初始化设置管理器
	 */
	public async initialize(): Promise<void> {
		try {
			// 1. 首先加载默认设置
			this._defaultSettings = await this.loadDefaultSettings()

			// 2. 尝试从本地缓存加载设置
			const cachedSettings = this.loadCachedSettings()

			// 3. 如果有缓存设置，合并默认设置和缓存设置
			if (cachedSettings) {
				this._settings = this.mergeSettings(this._defaultSettings, cachedSettings)
				console.log('已加载缓存设置')
			} else {
				// 没有缓存设置，使用默认设置
				this._settings = { ...this._defaultSettings }
				console.log('使用默认设置')
			}
		} catch (error) {
			console.error('初始化设置失败:', error)
			// 初始化失败时使用空对象
			this._settings = {} as T
			// 子类可以覆盖 handleInitError 方法提供默认值
			this.handleInitError(error)
		}
	}

	/**
	 * 处理初始化错误
	 * 子类可以覆盖此方法提供默认值
	 */
	protected handleInitError(error: any): void {
		// 默认实现为空
	}

	/**
	 * 加载默认设置
	 */
	protected async loadDefaultSettings(): Promise<T> {
		try {
			const settings = await ZAssetManager.instance.loadJson<T>(this.DEFAULT_SETTINGS_PATH)
			return settings
		} catch (error) {
			console.error('加载默认设置失败:', error)
			throw error
		}
	}

	/**
	 * 从本地缓存加载设置
	 * 只加载需要持久化的属性
	 */
	protected loadCachedSettings(): Partial<T> | null {
		try {
			const cachedSettingsStr = sys.localStorage.getItem(this.SETTINGS_CACHE_KEY)
			if (cachedSettingsStr) {
				const allCachedSettings = JSON.parse(cachedSettingsStr)

				// 如果没有定义持久化键，返回所有缓存设置
				if (!this.PERSISTENT_KEYS || this.PERSISTENT_KEYS.length === 0) {
					return allCachedSettings
				}

				// 只返回需要持久化的属性
				const persistentSettings: Partial<T> = {}
				for (const key of this.PERSISTENT_KEYS) {
					if (key in allCachedSettings) {
						persistentSettings[key] = allCachedSettings[key]
					}
				}

				return persistentSettings
			}
			return null
		} catch (error) {
			console.error('加载缓存设置失败:', error)
			return null
		}
	}

	/**
	 * 保存设置到本地缓存
	 * 只保存需要持久化的属性
	 */
	protected saveCachedSettings(): void {
		try {
			// 如果没有定义持久化键，保存所有设置
			if (!this.PERSISTENT_KEYS || this.PERSISTENT_KEYS.length === 0) {
				const settingsStr = JSON.stringify(this._settings)
				sys.localStorage.setItem(this.SETTINGS_CACHE_KEY, settingsStr)
				console.log('所有设置已保存到本地缓存')
				return
			}

			// 只保存需要持久化的属性
			const persistentSettings: Partial<T> = {}
			for (const key of this.PERSISTENT_KEYS) {
				persistentSettings[key] = this._settings[key]
			}

			const settingsStr = JSON.stringify(persistentSettings)
			sys.localStorage.setItem(this.SETTINGS_CACHE_KEY, settingsStr)
			console.log('持久化设置已保存到本地缓存')
		} catch (error) {
			console.error('保存设置到缓存失败:', error)
		}
	}

	/**
	 * 合并设置
	 * 确保所有默认设置的字段都存在
	 */
	protected mergeSettings(defaultSettings: T, cachedSettings: Partial<T>): T {
		// 创建一个新对象，基于默认设置
		const mergedSettings = { ...defaultSettings }

		// 用缓存设置覆盖默认设置的值
		for (const key in cachedSettings) {
			if (key in defaultSettings) {
				mergedSettings[key] = cachedSettings[key]
			}
		}

		return mergedSettings
	}

	/**
	 * 获取当前设置
	 */
	public get settings(): T {
		return this._settings
	}

	/**
	 * 获取特定设置项
	 */
	public getSetting<K extends keyof T>(key: K): T[K] {
		return this._settings[key]
	}

	/**
	 * 更新设置
	 * @param key 设置键
	 * @param value 设置值
	 * @param save 是否保存到缓存（默认为true）
	 */
	public updateSetting<K extends keyof T>(key: K, value: T[K], save: boolean = true): void {
		if (this._settings[key] !== value) {
			this._settings[key] = value

			// 如果需要保存，且该属性需要持久化，则保存到缓存
			if (save && this.shouldPersist(key)) {
				this.saveCachedSettings()
			}
		}
	}

	/**
	 * 批量更新设置
	 * @param partialSettings 部分设置
	 * @param save 是否保存到缓存（默认为true）
	 */
	public updateSettings(partialSettings: Partial<T>, save: boolean = true): void {
		let hasChanges = false
		let hasPersistentChanges = false

		for (const key in partialSettings) {
			if (key in this._settings && this._settings[key] !== partialSettings[key]) {
				this._settings[key] = partialSettings[key]
				hasChanges = true

				// 检查是否有持久化属性变更
				if (this.shouldPersist(key as keyof T)) {
					hasPersistentChanges = true
				}
			}
		}

		// 如果有持久化属性变更，且需要保存，则保存到缓存
		if (save && hasPersistentChanges) {
			this.saveCachedSettings()
		}
	}

	/**
	 * 检查属性是否需要持久化
	 * @param key 属性键
	 * @returns 是否需要持久化
	 */
	protected shouldPersist(key: keyof T): boolean {
		// 如果没有定义持久化键，则所有属性都持久化
		if (!this.PERSISTENT_KEYS || this.PERSISTENT_KEYS.length === 0) {
			return true
		}

		// 检查属性是否在持久化键列表中
		return this.PERSISTENT_KEYS.includes(key)
	}

	/**
	 * 重置所有设置为默认值
	 */
	public resetToDefaults(): void {
		this._settings = { ...this._defaultSettings }
		this.saveCachedSettings()
		console.log('设置已重置为默认值')
	}

	/**
	 * 清除缓存的设置
	 */
	public clearCachedSettings(): void {
		sys.localStorage.removeItem(this.SETTINGS_CACHE_KEY)
		console.log('缓存设置已清除')
	}
}
